# coding=UTF-8
# Filename:ClientUI.py
import Tkinter
import tkFont
import socket
import thread
import time
import sys


class ClientUI(object):

    title = 'Client'
    local = '10.167.192.145'
    port = 9999
    global clientSock
    flag = False

    def __init__(self):
        self.root = Tkinter.Tk()
        self.root.title(self.title)
        self.photo = Tkinter.PhotoImage(file='20140714115947_mJavd.gif')

        # 窗口面板，用4个frame面板布局
        self.frame = [Tkinter.Frame(), Tkinter.Frame(), Tkinter.Frame(), Tkinter.Frame()]

        # 显示消息Text右边的滚动条
        self.chatTextScrollBar = Tkinter.Scrollbar(self.frame[0])
        self.chatTextScrollBar.pack(side=Tkinter.RIGHT, fill=Tkinter.Y)

        # 显示消息Text，并绑定上面的滚动条
        ft = tkFont.Font(family='Fixdsys', size=11)
        self.chatText = Tkinter.Listbox(self.frame[0], width=70, height=18, font=ft)
        self.chatText['yscrollcommand'] = self.chatTextScrollBar.set
        self.chatText.pack(expand=1, fill=Tkinter.BOTH)
        self.chatTextScrollBar['command'] = self.chatText.yview()
        self.frame[0].pack(expand=1, fill=Tkinter.BOTH)

        # 标签，分开消息显示Text和消息输入Text
        label = Tkinter.Label(self.frame[1], height=120, image=self.photo)
        label.pack(fill=Tkinter.BOTH)
        self.frame[1].pack(expand=1, fill=Tkinter.BOTH)

        # 输入消息Text的滚动条
        self.inputTextScrollBar = Tkinter.Scrollbar(self.frame[2])
        self.inputTextScrollBar.pack(side=Tkinter.RIGHT, fill=Tkinter.Y)

        # 输入消息Text， 并与滚动条绑定
        ft = tkFont.Font(family='Fixdsys', size=11)
        self.inputText = Tkinter.Text(self.frame[2], width=70, height=8, font=ft)
        self.inputText['yscrollcommand'] = self.inputTextScrollBar.set
        self.inputText.pack(expand=1, fill=Tkinter.BOTH)
        self.inputTextScrollBar['command'] = self.chatText.yview()
        self.frame[2].pack(expand=1, fill=Tkinter.BOTH)

        # 发送信息按钮
        self.sendButton = Tkinter.Button(self.frame[3], text='发送', width=10, command=self.sendMessage)
        self.sendButton.pack(expand=1, side=Tkinter.BOTTOM and Tkinter.LEFT, padx=15, pady=8)

        # 关闭按钮
        self.closeButton = Tkinter.Button(self.frame[3], text='关闭', width=10, command=self.close)
        self.closeButton.pack(expand=1, side=Tkinter.RIGHT, padx=15, pady=8)
        self.frame[3].pack(expand=1, fill=Tkinter.BOTH)

        # 连接按钮
        self.connectionButton = Tkinter.Button(self.frame[3], text='连接', width=10, command=self.connection_socket)
        self.connectionButton.pack(expand=1, side=Tkinter.LEFT, padx=15, pady=8)
        self.frame[3].pack(expand=1, fill=Tkinter.BOTH)

        # 重新连接按钮
        self.reconnectionButton = Tkinter.Button(self.frame[3], text='重新连接', width=10, command=self.reconnection_socket)
        self.reconnectionButton.pack(expand=1, side=Tkinter.RIGHT, padx=15, pady=8)
        self.frame[3].pack(expand=1, fill=Tkinter.BOTH)

        # 清除聊天内容
        self.clean_upButton = Tkinter.Button(self.frame[1], text='清空', width=10, command=self.clean_up)
        self.clean_upButton.pack(expand=1, side=Tkinter.RIGHT, padx=15, pady=8)
        self.frame[1].pack(expand=1, fill=Tkinter.BOTH)

    # 接受消息
    def receiveMessage(self):
        # 建立Socket连接
        try:
            self.clientSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.clientSock.connect((self.local, self.port))
            self.chatText.insert(Tkinter.END, '★--与Evan成功建立连接--★')
            self.flag = True
        except Exception:
            self.flag = False
            self.chatText.insert(Tkinter.END, '您还未与Evan建立连接，请呼叫Evan启动服务器!')
            return

        self.buffer_size = 1024
        self.clientSock.send("Hi Evan, I'm Jane")
        while True:
            try:
                if self.flag == True:
                    # 连接建立， 接受服务器端消息
                    try:
                        self.serverMsg = self.clientSock.recv(self.buffer_size)
                    except Exception:
                        self.chatText.insert(Tkinter.END, '☆--已断开连接--☆\n')
                        self.flag = False
                        break

                    if not self.serverMsg:
                        continue

                    theTime = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())
                    self.chatText.insert(Tkinter.END, 'Evan ' + theTime + ':\n')
                    self.chatText.insert(Tkinter.END, ' ' + self.serverMsg)
                else:
                    break
            except EOFError, msg:
                print 'EOFError msg:{}'.format(msg)
                self.clientSock.close()
                break

    # 发送消息
    def sendMessage(self):
        # 得到用户在Text中输入的消息
        message = self.inputText.get('1.0', Tkinter.END)
        # 格式化当前的时间
        thetime = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())

        if self.flag == True:
            # 将消息发送到服务器端
            self.chatText.insert(Tkinter.END, 'Jane ' + thetime + ':\n')
            self.chatText.insert(Tkinter.END, ' ' + message + '\n')
            self.clientSock.send(message)
            # 清空用户在Text中输入的消息
            self.inputText.delete(0.0, message.__len__() - 1.0)
        else:
            # Socket连接没有建立， 提示用户
            self.chatText.insert(Tkinter.END, '您还未与Evan建立连接，Evan无法收到您的消息\n')
            # 清空用户在Text中输入的消息
            self.inputText.delete(0.0, message.__len__()-1.0)

    # 关闭消息窗口并退出
    def close(self):
        sys.exit()

    # 启动线程接受服务器端的消息
    def startNewThread(self):
        # 启动一个新线程来接受服务器端的消息
        thread.start_new_thread(self.receiveMessage, ())

    # 连接服务器端
    def connection_socket(self):
        self.startNewThread()

    # 重新连接服务器端
    def reconnection_socket(self):
        self.clientSock.send('Jane正在重新进行连接...')
        self.clientSock.close()
        self.chatText.insert(Tkinter.END, '正在重新进行连接...')
        self.startNewThread()

    # 清空聊天内容
    def clean_up(self):
        self.chatText.delete(0, Tkinter.END)


def main():
    client = ClientUI()
    client.root.mainloop()


if __name__ == '__main__':
    main()
